﻿
#include "CreateLineDlg.h"
#include <vtkLineSource.h>
#include <vtkActor.h>    
#include <vtkAssembly.h>    
#include <vtkLODActor.h>    
#include <vtkPolyDataMapper.h>    
#include <vtkDataSetMapper.h>
#include <vtkMultiProcessController.h>
#include <vtkVolume.h>
#include <vtkGpuVolumeRayCastMapper.h>
#include <vtkOpenGLGPUVolumeRayCastMapper.h>
#include <vtkSmartPointer.h>
#include <vtkOpenGLVertexBufferObject.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkOpenGLPolyDataMapper.h>
#include <vtkOpenGLVertexArrayObject.h>
#include <vtkVolumeMapper.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkPointGaussianMapper.h>
#include <vtkGlyph3DMapper.h>
#include <vtkAppendPolyData.h>
#include <vtkOpenGLRenderer.h>



CreateLineDlg::CreateLineDlg(QWidget* parent):
    DlgBase(parent)
{
    initUI();
    manageConnections();
}

CreateLineDlg::~CreateLineDlg()
{
}

bool CreateLineDlg::create()
{
    auto pVtkViewWindow = MyVtkViewWindow::GetInstance();
    if(pVtkViewWindow == nullptr)
    {
        return false;
    }

    m_startPointCoord->getValues(m_startPoint[0], m_startPoint[1], m_startPoint[2]);
    m_endPointCoord->getValues(m_endPoint[0], m_endPoint[1], m_endPoint[2]);


    //1合并为一个Actor，提高渲染效率，缺点无法单独个性化actor
    {
        //create vtk vtkLineSource
        vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
        lineSource->SetPoint1(m_startPoint);
        lineSource->SetPoint2(m_endPoint);
        lineSource->Update();

        vtkSmartPointer<vtkAppendPolyData> lineData = vtkSmartPointer<vtkAppendPolyData>::New();


        for(int lineCount = 1E3, i = 0; i < lineCount; ++i)
        {
            // 创建变换
            vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
            double dAngle = 360.0 / lineCount * (i + 1);
            transform->RotateX(dAngle);
            transform->RotateY(dAngle);
            transform->RotateZ(dAngle);
            transform->Translate(0.5, 0.5, 0.5);
            transform->Update();

            // 应用变换
            vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
            transformFilter->SetInputData(lineSource->GetOutput());
            transformFilter->SetTransform(transform);
            transformFilter->Update();

            lineData->AddInputData(transformFilter->GetOutput());
            lineData->Update();
            qDebug() << "actor = " << i;
        }


        vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        lineMapper->SetInputData(lineData->GetOutput());
        //lineMapper->StaticOn();//设置静态属性，提高效率


        vtkSmartPointer<vtkLODActor> lineActor = vtkSmartPointer<vtkLODActor>::New();
        lineActor->SetMapper(lineMapper);
        double color[3] = {1,0, 0};
        lineActor->GetProperty()->SetColor(color[0], color[1], color[2]);  //set line color
        lineActor->GetProperty()->SetLineWidth(QtVtkModle::Global::LineWidth);
        lineActor->SetPosition(10, 10, 10);

        //add line to vtk view
        pVtkViewWindow->GetRenderer()->AddActor(lineActor);
        GetActorManagerInstance()->AddActor(lineActor, PickMode::EDGE);
    }


    //2 使用一个mapper，多个actor，每个actor单独设置颜色，位置，大小，旋转，提高渲染效率
    //{
    //    //create vtk vtkLineSource
    //    vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
    //    lineSource->SetPoint1(m_startPoint);
    //    lineSource->SetPoint2(m_endPoint);
    //    lineSource->Update();

    //    vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    //    lineMapper->SetInputConnection(lineSource->GetOutputPort());
    //    lineMapper->StaticOn();//设置静态属性，提高效率
    //    lineMapper->SetVBOShiftScaleMethod(vtkPolyDataMapper::AUTO_SHIFT_SCALE);//设置VBO优化方法，提高渲染效率(提升很低1%)


    //    for(int lineCount = 1E3, i = 0; i < lineCount; ++i)
    //    {
    //        // 创建变换
    //        vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
    //        double dAngle = 360.0 / lineCount * (i + 1);
    //        transform->RotateX(dAngle);
    //        transform->RotateY(dAngle);
    //        transform->RotateZ(dAngle);
    //        transform->Translate(0.5, 0.5, 0.5);


    //        vtkSmartPointer<vtkLODActor> lineActor = vtkSmartPointer<vtkLODActor>::New();
    //        lineActor->SetMapper(lineMapper);
    //        double color[3] = {0.5 / lineCount * i, 1.0 / lineCount * (i + 1), 0};
    //        lineActor->GetProperty()->SetColor(color[0], color[1], color[2]);  //set line color
    //        lineActor->GetProperty()->SetLineWidth(QtVtkModle::Global::LineWidth);
    //        lineActor->SetUserTransform(transform);

    //        //add line to vtk view
    //        pVtkViewWindow->GetRenderer()->AddActor(lineActor);
    //    }
    //}

    //3 使用mapper static属性，多个actor，每个actor单独设置颜色，位置，大小，旋转，提高渲染效率
    vtkSmartPointer<vtkAssembly> lineActorFather = vtkSmartPointer<vtkAssembly>::New();

    //for(int lineCount = 1E3, i = 0; i < lineCount; ++i)
    //{
    //    //create vtk vtklinesource
    //    vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
    //    lineSource->SetPoint1(m_startPoint);
    //    lineSource->SetPoint2(m_endPoint);
    //    lineSource->Update();

    //    //创建变换
    //    vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
    //    double dAngle = 360.0 / lineCount * (i + 1);
    //    transform->RotateX(dAngle);
    //    transform->RotateY(dAngle);
    //    transform->RotateZ(dAngle);
    //    transform->Translate(0.5, 0.5, 0.5);

    //    // 应用变换
    //    vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
    //    transformFilter->SetInputData(lineSource->GetOutput());
    //    transformFilter->SetTransform(transform);
    //    //transformFilter->Update();

    //    vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    //    lineMapper->SetInputConnection(transformFilter->GetOutputPort());
    //    lineMapper->Update();//mapper数据必须更新Update
    //    lineMapper->StaticOn();//设置静态属性，提高渲染效率(提升40%),使用该属性，mapper数据必须更新Update
    //    lineMapper->SetVBOShiftScaleMethod(vtkPolyDataMapper::AUTO_SHIFT_SCALE);//设置VBO优化方法，提高渲染效率(提升很低1%)


    //    vtkSmartPointer<vtkLODActor> lineActor = vtkSmartPointer<vtkLODActor>::New();
    //    lineActor->SetMapper(lineMapper);
    //    //lineActor->GetProperty()->SetColor(QtVtkModle::Global::LineColor[0], QtVtkModle::Global::LineColor[1], QtVtkModle::Global::LineColor[2]);  //set line color
    //    double color[3] = {0.5 / lineCount * i, 1.0 / lineCount * (i + 1), 0};
    //    lineActor->GetProperty()->SetColor(color[0], color[1], color[2]);  //set line color
    //    lineActor->GetProperty()->SetLineWidth(QtVtkModle::Global::LineWidth);

    //    //add line to vtk view
    //    pVtkViewWindow->GetRenderer()->AddActor(lineActor);

    //    /* lineActorFather->AddPart(lineActor);
    //     if(i % 2 == 0)
    //     {
    //         lineActor->VisibilityOff();
    //     }*/
    //}

    //pVtkViewWindow->GetRenderer()->AddActor(lineActorFather);

    pVtkViewWindow->ResetRenderersCamera();
    pVtkViewWindow->GetRenderWindow()->Render();

    //// 假设你有一个vtkActorCollection
    //vtkSmartPointer<vtkActorCollection> actorCollection = pVtkViewWindow->GetRenderer()->GetActors();

    //// 遍历所有actor并设置其mapper为静态
    //actorCollection->InitTraversal();
    //vtkActor* actor = actorCollection->GetNextActor();
    //while(actor != nullptr)
    //{
    //    vtkMapper* mapper = actor->GetMapper();
    //    if(mapper != nullptr)
    //    {
    //        // 确保mapper有有效数据
    //        if(mapper->GetInput() != nullptr || mapper->GetInputConnection(0, 0) != nullptr)
    //        {
    //            // 重要：在设置静态前确保数据已更新
    //            mapper->Update();
    //            //mapper->SetStatic(true);
    //        }
    //        else
    //        {
    //            std::cout << "警告：Mapper没有有效输入数据" << std::endl;
    //        }
    //    }
    //    actor = actorCollection->GetNextActor();
    //}

    return true;
}

void CreateLineDlg::initUI()
{
    setWindowTitle("Create Line");
    QVBoxLayout* pDlgLayout = new QVBoxLayout(this);  //create layout

    {
        m_startPointCoord = new MyCoordinateEdit(this, "Start Point");
        pDlgLayout->addWidget(m_startPointCoord);

        m_endPointCoord = new MyCoordinateEdit(this, "End Point");
        m_endPointCoord->setValues(1, 1, 1);
        pDlgLayout->addWidget(m_endPointCoord);
    }

    {
        m_okBtn = new QPushButton("OK", this);
        m_cancelBtn = new QPushButton("Cancel", this);

        QHBoxLayout* okCancelLayout = new QHBoxLayout(this);
        okCancelLayout->addWidget(m_okBtn);
        okCancelLayout->addWidget(m_cancelBtn);
        pDlgLayout->addLayout(okCancelLayout);
    }

    this->setLayout(pDlgLayout);
}

void CreateLineDlg::manageConnections()
{
    connect(m_okBtn, &QPushButton::clicked, this, [=]()
            {
                if(create())
                {
                    close();
                }
                else
                {
                    QMessageBox::warning(this, "Error", "Failed to create line!");
                }

            });

    connect(m_cancelBtn, &QPushButton::clicked, this, &CreateLineDlg::close);
}



